
--属性编辑
local field = {}


local mt = ac.unit.__index

local function get_attr_data(self,name,class,value)
	local name_type = 0
	if name:sub(-1, -1) == '%' then
		name = name:sub(1, -2)
		name_type = 1
	end
    
    local field_data = field[name]
	if not field_data then
		log.error(('[unit]错误的属性名1:[%s][%s]'):format(self:get_name(), name))
		return
	end

	local attr = self.attributes
	local key1 = name
	local key2 = name .. '%'

	if not attr[key1] then
        local value = field_data.get and field_data.get(self) or field_data.value or 0
        attr[key1] = value
        attr[key2] = 0
	end
    if class=='get' then
        if name_type==0 then
            local value = attr[key1] * (1 + attr[key2] / 100)
            if field_data.on_get then
                value = field_data.on_get(self,value)
            end
            return value
        else
            return attr[key2]
        end

    elseif class=='set' and name_type==0 then
        local old_value = attr[key1] * (1 + attr[key2] / 100)
        local f
    
        if field_data.on_set then
            --需要对变动数据进行处理
            local v1 = attr[key1]
            f = field_data.on_set(self, value, value - v1)
        end
        attr[key1] = value
        attr[key2] = 0

        if field_data.set then
            field_data.set(self, attr[key1] * (1 + attr[key2] / 100), old_value)
        end
        if f then
            f()
        end

    elseif class=='add' then
        local old_value = attr[key1] * (1 + attr[key2] / 100)

        local f
        if field_data.on_set then
            local v1 = attr[key1]
            f = field_data.on_set(self, value, value - v1)
        end
    
        if name_type==0 then
            attr[key1] = attr[key1] + value
        elseif name_type==1 then
            attr[key2] = attr[key2] + value
        end
        if field_data.set then
            field_data.set(self, attr[key1] * (1 + attr[key2] / 100), old_value)
        end
        if f then
            f()
        end
    
    end
    
end

--数据增加
function mt:add(name,value)
	get_attr_data(self,name,'add',value)
	local used
    return function ()
        if used then
            return
        end
		if self.removed then return end
        used = true
        return self:add(name, -value)
    end
end

--数据设置
function mt:set(name,value)
	get_attr_data(self,name,'set',value)
end


--数据获取
function mt:get(name)
	return get_attr_data(self,name,'get')
end

--注册属性
function register(name,...)
    local param = {...}
    local data = field[name] or {}
    data.name = name
    if #param==1 and type(param[1])=='table' then
        for k,v in pairs(param[1]) do
            data[k] = v
        end
    else
        data.value = param[1]
    end

    field[name] = data
end



register('当前生命百分比',{
    on_get = function(self)
        local rate = 1
        if self:get('生命上限')>0 then
            rate = self:get '生命' / self:get '生命上限'
        end
        return rate * 100
    end,
})
register('生命',{
    get = function(self)
        return jass.GetWidgetLife(self.handle)
    end,
    on_get = function(self,life)
        if life < 0 then
            return 0
        else
            local max_life = self:get '生命上限'
            if life > max_life then
                return max_life
            end
        end
        return life
    end,
    set = function(self, new_value, old_value)
        local min_life = 1
        local max_life = self:get '生命上限'
        if new_value > max_life then
            new_value = max_life
        elseif new_value < min_life then
            new_value = min_life
        end
        self.attributes['生命'] = new_value
        jass.SetWidgetLife(self.handle, new_value)
    end,
})

register('额外生命',{
    on_set = function(self,value,change)
        self:add('生命上限',change)
    end
})

register('生命上限',{
    get = function(self)
        return japi.GetUnitState(self.handle, jass.ConvertUnitState(1))
    end,
    set = function(self, new_value, old_value)
	    japi.SetUnitState(self.handle, jass.ConvertUnitState(1), new_value)
    end,
    on_set = function(self,value)
        local rate = self:get '当前生命百分比' / 100
        return function()
            self:set('生命', self:get '生命上限' * rate)
        end
    end,
})

register('生命恢复',{
    set = function(self,value,change)
        self:refresh_regen()
    end
})
register('生命百分比恢复',{
    set = function(self,value,change)
        self:refresh_regen()
    end
})

register('护盾')

register('护盾上限',{
    on_get = function(self)
        return self:get('生命上限')
    end
})

register('当前魔法百分比',{
    on_get = function(self)
        local rate = 1
        if self:get('魔法上限')>0 then
            rate = self:get '魔法' / self:get '魔法上限'
        end
        return rate * 100
    end,
})

register('魔法',{
    get = function(self)
        return jass.GetUnitState(self.handle, jass.ConvertUnitState(2))
    end,
    on_get = function(self,life)
        if life < 0 then
            return 0
        else
            local max_life = self:get '魔法上限'
            if life > max_life then
                return max_life
            end
        end
        return life
    end,
    set = function(self, new_value, old_value)
        local min_life = 1
        local max_life = self:get '魔法上限'
        if new_value > max_life then
            new_value = max_life
        elseif new_value < min_life then
            new_value = min_life
        end
        self.attributes['魔法'] = new_value
        jass.SetUnitState(self.handle, jass.ConvertUnitState(2), new_value)
    end,
})

register('魔法上限',{
    get = function(self)
        return japi.GetUnitState(self.handle, jass.ConvertUnitState(3))
    end,
    set = function(self, new_value, old_value)
	    japi.SetUnitState(self.handle, jass.ConvertUnitState(3), new_value)
    end,
    on_set = function(self,value)
        local rate = self:get '当前魔法百分比' / 100
        return function()
            self:set('魔法', self:get '魔法上限' * rate)
        end
    end,
})

register('魔法恢复',{
    set = function(self,value,change)
        self:refresh_regen()
    end
})

register('魔法百分比恢复',{
    set = function(self,value,change)
        self:refresh_regen()
    end
})


--三维处理
local function hero_attribute(hero,name)
    if hero.main_attribute==name then

    end
    if name=='力量' then
        
    end
    if name=='敏捷' then
        
    end
    if name=='智力' then
        
    end
end


--绿字属性处理
local abiid = {}
abiid['攻击'] = string.unpack('>I4', '+Atk')
abiid['护甲'] = string.unpack('>I4', '+Amr')
abiid['力量'] = string.unpack('>I4', '+Str')
abiid['敏捷'] = string.unpack('>I4', '+Agi')
abiid['智力'] = string.unpack('>I4', '+Int')
local attrs = {'攻击','护甲','力量','敏捷','智力'}
for i,name in ipairs(attrs) do
    local base = ('基础%s'):format(name)
    local exsx = ('额外%s'):format(name)
    local rate = ('%s加成'):format(name)
    --总属性
    register(name,{
        on_get = function(self)
            return self:get(base) + self:get(exsx)
        end,
    })

    --基础
    register(base,{
        get = function(self)
            if name=='攻击' then
	            return japi.GetUnitState(self.handle, jass.ConvertUnitState(0x12))
            elseif name=='护甲' then
	            return japi.GetUnitState(self.handle, jass.ConvertUnitState(0x20))  - self:get('额外护甲')
            elseif name=='力量' then
                return jass.GetHeroStr(self.handle,true)
            elseif name=='敏捷' then
                return jass.GetHeroAgi(self.handle,true)
            elseif name=='敏捷' then
                return jass.GetHeroInt(self.handle,true)
            end
        end,
        set = function(self,value, old_value)
            if name=='攻击' then
	            japi.SetUnitState(self.handle, jass.ConvertUnitState(0x12), value)
            elseif name=='护甲' then
	            japi.SetUnitState(self.handle, jass.ConvertUnitState(0x20), value  + self:get('额外护甲'))
            elseif name=='力量' then
                jass.SetHeroStr(self.handle,math.floor(value),true)
            elseif name=='敏捷' then
                jass.SetHeroAgi(self.handle,math.floor(value),true)
            elseif name=='敏捷' then
                jass.SetHeroInt(self.handle,math.floor(value),true)
            end
            if name=='力量' or name=='敏捷' or name=='智力' then
                hero_attribute(self,name,value - old_value)
            end
            
            self:set(exsx,self:get(rate) * value / 100)

        end,
    })

    --额外
    local spid = abiid[i]
    register(exsx,{
        set = function(self,value,old_value)
            self:add_ability(spid)
            jass.SetUnitAbilityLevel(self.handle, spid, 2)
            japi.EXSetAbilityDataReal(japi.EXGetUnitAbility(self.handle, spid), 1, 108, value)
            jass.SetUnitAbilityLevel(self.handle, spid, 1)
            
            if name=='力量' or name=='敏捷' or name=='智力' then
                hero_attribute(self,name,value - old_value)
            end
        end
    })

    --加成
    register(rate,{
        set = function(self,value)
            self:set(exsx,self:get(base) * value / 100)
        end
    })
end

register('冷却缩减',{
    on_set = function(self,value)
        local t = {}
        for skl in self:each_skill() do
            local f = skl:fresh_cool()
            table.insert(t, f)
        end
        return function()
            for _, f in ipairs(t) do
                f()
            end
        end
    end,
})

register('攻击距离',{
    get = function(self,value)
        return japi.GetUnitState(self.handle, jass.ConvertUnitState(0x16))
    end,
    set = function(self,value)
        japi.SetUnitState(self.handle, jass.ConvertUnitState(0x16), value)
        if jass.GetUnitAcquireRange(self.handle) < value then
            jass.SetUnitAcquireRange(self.handle, value)
        end
    end
})

register('索敌范围',{
    get = function(self,value)
        return jass.GetUnitAcquireRange(self.handle)
    end,
    set = function(self,value)
	    jass.SetUnitAcquireRange(self.handle, value)
    end
})


register('攻击速度',{
    get = function(self,value)
        return japi.GetUnitState(self.handle, jass.ConvertUnitState(0x51)) * 100
    end,
    set = function(self,attack_speed)
        if attack_speed >= 100 then
            japi.SetUnitState(self.handle, jass.ConvertUnitState(0x51),attack_speed / 100)
        else
            -- 当攻击速度小于 0 的时候,每点相当于攻击间隔增加 1%
            japi.SetUnitState(self.handle, jass.ConvertUnitState(0x51),attack_speed / (100 - attack_speed))
        end
    end
})

register('攻击间隔',{
    get = function(self,value)
        return japi.GetUnitState(self.handle, jass.ConvertUnitState(0x25))
    end,
    set = function(self,attack_cool)
        japi.SetUnitState(self.handle, jass.ConvertUnitState(0x25), attack_cool)
    end
})

register('单位体型',{
    get = function(self,value)
        return 100
    end,
    on_set = function(self)
        return function()
            self:set_scale(self:get_scale())
        end
    end
})

register('移动速度',{
    get = function(self,value)
        return jass.GetUnitDefaultMoveSpeed(self.handle)
    end,
    set = function(self,value)
        jass.SetUnitMoveSpeed(self.handle, value)
    end
})


register('治疗效果')

return {
    register = register,
    field = field,
}